package com.zp.imagecompresspractice.View;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;

import com.zp.imagecompresspractice.R;

/**
 * Created by izp on 2017/7/20.
 */

public class ShapeIndicatorView extends View  implements TabLayout.OnTabSelectedListener,ViewPager.OnPageChangeListener{

    private Paint mShapePaint;
    private Path mShapePath;
    private int mShapeHorizontalSpace;
    private int mShapeColor = Color.GREEN;

    private TabLayout mTabLayout;
    private ViewPager mViewPager;

    public ShapeIndicatorView(Context context) {
        super(context);
        initViews(context,null,-1,-1);
    }

    public ShapeIndicatorView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initViews(context,attrs,-1,-1);
    }

    public ShapeIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initViews(context,attrs,defStyleAttr,-1);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public ShapeIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initViews(context,attrs,defStyleAttr,defStyleRes);
    }

    private void initViews(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes){
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShapeIndicatorView,defStyleRes,0);
        mShapeHorizontalSpace = typedArray.getInteger(R.styleable.ShapeIndicatorView_horizontalSpace,15);
        mShapeColor = typedArray.getColor(R.styleable.ShapeIndicatorView_fullColor,Color.GREEN);
        int radius = typedArray.getInteger(R.styleable.ShapeIndicatorView_radius,50);
        typedArray.recycle();
        mShapePaint = new Paint();
        mShapePaint.setAntiAlias(true);
        mShapePaint.setDither(true);//防抖动
        mShapePaint.setColor(mShapeColor);
        mShapePaint.setStyle(Paint.Style.FILL);
        mShapePaint.setPathEffect(new CornerPathEffect(radius));//50个px
        mShapePaint.setStrokeCap(Paint.Cap.ROUND);//这个也是笔刷转角，或者是断点 的圆角，默认是圆
    }

    public void bindWithTabLayout(TabLayout tabLayout){
        mTabLayout = tabLayout;
        mTabLayout.setSelectedTabIndicatorColor(Color.TRANSPARENT);
        mTabLayout.addOnTabSelectedListener(this);
        mTabLayout.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener(){

            @Override
            public void onScrollChanged() {
                KLog.v("mTabLayout.getScrollX()"+mTabLayout.getScrollX()+" != getScrollX()"+getScrollX());
                if (mTabLayout.getScrollX() != getScrollX()){//如果获取的tabLayout的scrollX和当前的view的ScrollX不相等，则移动到
                    scrollTo(mTabLayout.getScrollX(), mTabLayout.getScrollY());
                }
            }
        });
        KLog.v("ViewCompat.getElevation(mTabLayout))"+ViewCompat.getElevation(mTabLayout));
        ViewCompat.setElevation(this,ViewCompat.getElevation(mTabLayout));//这一段也没看懂，设置阴影怎么弄
        KLog.v("mTabLayout.getTabCount()"+mTabLayout.getTabCount());
        mTabLayout.post(new Runnable() {
            @Override
            public void run() {
                if (mTabLayout.getTabCount() > 0){
                    onTabSelected(mTabLayout.getTabAt(0));//初始化tabLayout的选择位置
                }
            }
        });
        //清除Tab background
        for (int tab=0;tab<tabLayout.getTabCount();tab++){
            View tabView =getTabViewByPosition(tab);
            if (null!=tabView){
                tabView.setBackgroundResource(0);
            }
        }
    }

    /**
     * @param viewPager
     *
     */
    public void bindWithViewPager(ViewPager viewPager){
        mViewPager = viewPager;
        mViewPager.addOnPageChangeListener(this);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawPath(canvas);
    }

    private void drawPath(Canvas canvas){
        if (mShapePath == null || mShapePath.isEmpty()){//如果路径为空或者路径没有初始化，就返回
            return;
        }
        int savePosition = canvas.save();//保存画笔，并返回一个图层，当前是图层1
        canvas.drawPath(mShapePath,mShapePaint);//传入路径和画笔来绘制图像
        canvas.restoreToCount(savePosition);//恢复指定图层
    }


    /**
     * @param position
     * @return
     *
     */
    private View getTabViewByPosition(int position){
        if (mTabLayout!=null && mTabLayout.getTabCount()>0){
            ViewGroup tabStrip = (ViewGroup) mTabLayout.getChildAt(0);//tabLayout中的0应该是背景吧，所以这里也是不稳的
            return tabStrip!=null ? tabStrip.getChildAt(position) :null;//如果从0get的ViewGroup不为空，那么就从这个tab中再获取其中的View
        }
        return null;
    }

    /**
     * @param position 位置
     * @param positionOffset 这个偏移量到底是速度还是方向？
     * @return
     */
    private Path generatePath(int position,float positionOffset){
        RectF range = new RectF();
        View tabView = getTabViewByPosition(position);//获取tabLayout的tab的View
        if (tabView==null){
            return null;
        }
        int left,top,right,bottom;
        left = top = right = bottom =0;
//        这里的positionOffset是有正负的，所以offset有正负？
        KLog.v("positionOffset>0.f &&(左滑是正的)"+positionOffset+" position(当前position) "+position+"< mTabLayout.getTabCount()-1（数量就是adapter返回的count）"+mTabLayout.getTabCount());
        if (positionOffset>0.f && position < mTabLayout.getTabCount()-1){
            View nextTabView = getTabViewByPosition(position+1);
            if (null!=nextTabView){
//                tabView的right，是距离父控件左边的距离，所以肯定是比较大的，正值
//                tabView的bottom，是距离父控件的顶部的距离，肯定也很大，正值
                left += (int) (nextTabView.getLeft() * positionOffset + tabView.getLeft() * (1.0f - positionOffset));
                KLog.v("left +=(第一次滑的时候才11，) "+left+"(nextTabView.getLeft() *（第一次滑的时候286）"+nextTabView.getLeft()
                        +" positionOffset +"+positionOffset+" tabView.getLeft() *（第一次的时候是0，） "+tabView.getLeft()+
                        "(1.0f - positionOffset));"+(1.0f - positionOffset));
                right += (int)(nextTabView.getRight() * positionOffset + tabView.getRight() * (1.0f - positionOffset));
                KLog.v("right += "+right+"(int)(nextTabView.getRight() *"+nextTabView.getRight()
                        +" positionOffset +"+positionOffset+" tabView.getRight() * "+tabView.getRight()+"(1.0f - positionOffset));"+(1.0f - positionOffset));
                left += mShapeHorizontalSpace;//子View距离左边的距离加上一个空间，
                right -= mShapeHorizontalSpace;//子View距离左边的距离减去一个空间，（所以两个子View之间隔了两个space啊）
                KLog.v("left += "+left+"right:"+right+"mShapeHorizontalSpace;"+mShapeHorizontalSpace);
                top = tabView.getTop() + getPaddingTop();//加paddingTop就是向下压缩
                bottom = tabView.getBottom() - getPaddingBottom();//减去paddingBottom就是向上压缩
                KLog.v("top = "+top+"tabView.getTop() + "+tabView.getTop()+"getPaddingTop();"+getPaddingTop()+
                        "bottom = "+bottom+"tabView.getBottom() - "+tabView.getBottom()+"getPaddingBottom();"+getPaddingBottom());
                range.set(left,top,right,bottom);
            }
        }else {
            View nextTabView = getTabViewByPosition(position+1);
            if (null!=nextTabView){
                left = tabView.getLeft() + mShapeHorizontalSpace;
                right = tabView.getRight() - mShapeHorizontalSpace;
                KLog.v("left += "+left+"right:"+right+"mShapeHorizontalSpace;"+mShapeHorizontalSpace);
                top = tabView.getTop() + getPaddingTop();
                bottom = tabView.getBottom() - getPaddingBottom();
                KLog.v("top = "+top+"tabView.getTop() + "+tabView.getTop()+"getPaddingTop();"+getPaddingTop()+
                        "bottom = "+bottom+"tabView.getBottom() - "+tabView.getBottom()+"getPaddingBottom();"+getPaddingBottom());
                range.set(left,top,right,bottom);
                if (range.isEmpty()){
                    return mShapePath;
                }
            }
        }

        if (mShapePath==null){
            mShapePath = new Path();
        }

        Rect tabRect = getTabRange();//
        KLog.v("tabRect.right += "+tabRect.right+"tabRect.left:"+tabRect.left+"range.width();"+range.width());
        tabRect.right += range.width();//获取之前动态设置的range的宽高
        tabRect.left -= range.width();
        KLog.v("tabRect.right += "+tabRect.right+"tabRect.left:"+tabRect.left+"range.width();"+range.width());

        mShapePath.reset();//重置路径
//        开始画路径
        mShapePath.moveTo(tabRect.left,tabRect.bottom);


        mShapePath.lineTo(range.left,range.bottom);
        mShapePath.lineTo(range.left,range.top);
        mShapePath.lineTo(range.right,range.top);
        mShapePath.lineTo(range.right,range.bottom);


        mShapePath.lineTo(tabRect.right,tabRect.bottom);
        mShapePath.lineTo(tabRect.right,tabRect.top);
        mShapePath.lineTo(tabRect.left,tabRect.top);
        mShapePath.close();

        KLog.v("tabRect.left,"+tabRect.left+"tabRect.bottom :"+tabRect.bottom+"range.left,"+range.left+"range.bottom ("+range.bottom+
                "range.top :"+range.top+"range.right:"+range.right+"tabRect.right,"+tabRect.right+
                "tabRect.top ："+tabRect.top);

        return mShapePath;

    }

    /**
     * @return
     * 获取一个tab的范围
     */
    private Rect getTabRange(){
        Rect rect = null;
        if (mTabLayout != null){
            View view = mTabLayout.getChildAt(0);//获取tabLayout 中的子View
            rect = new Rect();
            view.getHitRect(rect);//获取矩形坐标
//            getHitRect(Rect outRect)这个方法用来找到控件占据的矩形区域的矩形坐标。 参数outRect表示控件占据的矩形区域。
        }
        return rect;
    }

//    tabLayout

    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        if (mViewPager!=null){
            if (tab.getPosition() !=mViewPager.getCurrentItem()){
                mViewPager.setCurrentItem(tab.getPosition());
            }
        }else {
            generatePath(tab.getPosition(),0);//如果没有viewPager，生成path，tab.getPosition，偏移量是0
            invalidate();
        }
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }

    /**
     * 当已经有一个ViewPager后，当TabLayout的tab改变的时候在onTabSelected方法直接调用ViewPager的
     * setCurrentItem方法调用这个方法后会触发ViewPager的scroll事件也就是在onPageScrolled方法中调用
     * generatePath方法来更新Path，如果没有ViewPager的话直接在onTabSelected的方法中调用generatePath
     * 方法。
     **/
//    viewPager

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        generatePath(position, positionOffset);
        invalidate();//重新绘制,每次都重新绘制会影响性能么？
    }

    @Override
    public void onPageSelected(int position) {
        if (mTabLayout.getSelectedTabPosition() != position){
            TabLayout.Tab tabAt = mTabLayout.getTabAt(position);
            if (null!=tabAt){
                tabAt.select();
            }
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}
